Arkansas Volleyball Team Optimizer & Simulator
Introduction
Our project is an interactive interface that allows for the user to build an Arkansas volleyball team from real player statistics from 2015-2025. It allows for them to evaluate the strengths, find the optimal team, and simulate matches against the last 5 national championship teams. We use player data from CSV files, including statistics such as kills, errors, aces, digs, and blocks to calculate a combined performance score for each player and then use these to compare team effectiveness. The purpose of our project is to combine data analysis, optimization, and simulation into a tool that helps users understand how individual performance impacts the overall teams success. This project applies Industrial Engineering concepts such as optimization modeling and probabilistic simulation. The optimal team feature uses integer programming to determine the optimal lineup, while the game simulator uses probability to model match outcomes based on team strength. Throughout this project, we used many important skills such as creating custom Java classes, working with ArrayLists and file input/output, and using external libraries like Tablesaw, Vaadin, OpenCSV, and OR-Tools. We each gained experience collaborating through sharing code and structuring a large, multi-class application.
Skills Used
Vaadin
Tablesaw
OR-Tools
OpenCSV
Interactive Website
Code Explanation

Our “Optimal Team” feature is designed to allow for the user to create the best possible six-player lineup using a data-driven analysis. Each player has statistics such as kills, errors, aces, digs, blocks, and sets played are converted into performance calculations like hitting percentage, digs per set, aces per set, and blocks per set. These calculations are then used to create a single weighted score for the individual player, where hitting percentage is weighted higher, followed by aces, with digs and blocks equally weighted. As the user selects six players in the interface, the system calculates a total team score by summing each individual player scores. This allows for the user to experiment with different combinations and then immediately seeing how their selections impact overall performance of the team, while also enforcing a constraint of only six players being chosen. The core component we use is the optimization model build using Google OR-Tools. We formed the problem as integer program, where each player is either selected or is not, and the objective is to maximize the total team score following the maximum 6 players constraint. The solver then identifies the optimal lineup giving the user a clear comparison from their chosen team and the best possible team based on the data.


Optimal Team
Loader.loadNativeLibraries(); MPSolver solver = MPSolver.createSolver(“SCIP”); int n = reveal.size();
//Creating a decision variables (0 or 1 for each player) (1 player selected, 0 player not selected)
MPVariable[] x = new MPVariable[n];
for (int i = 0; i < n; i++) {
x[i] = solver.makeIntVar(0, 1, "x_" + i);
}
//Constraint that they must select exactly 6 players
MPConstraint constraint = solver.makeConstraint(6, 6);
for (int i = 0; i < n; i++) {
constraint.setCoefficient(x[i], 1);
}
//Maximize total score
MPObjective objective = solver.objective();
for (int i = 0; i < n; i++) {
double score = ArkVolleyball.calcPlayerScore(reveal.get(i));
objective.setCoefficient(x[i], score);
}
objective.setMaximization();
//Solve the optimization problem
MPSolver.ResultStatus status = solver.solve();
List<ArkVolleyball> optimalTeam = new ArrayList<>();
Our “Game Simulator” feature has a user chosen 6-player team and uses it to simulate a match against one of the last 5 national championship teams. Similar to the Optimal Team, each player’s statistics are converted into performance calculations and each combined into a single player score. The individual scores are summed to create an overall team strength for the user’s lineup, while to opponent team’s strength is calculated from its data set. Using each team’s score, the interface calculates a win probability based on their relative strengths. The probability is then used to simulate a best-of-five match, where each set outcome is determined using a weighted random process. The stronger team has a higher chance of winning each set, but randomness is included so the results are completely deterministic, make the simulation much more realistic. The simulation then runs until one team wins three sets, and the results are displayed set-by-set along with the final score and win probability. Adding to this, we have team logos and a confetti effect when the user’s team wins, it allows for an engaging output. Overall, this feature demonstrates how probabilistic modeling can allow for a real-world simulation outcome bases on team performance data.



Simulator
int team1Sets = 0;
int opponentSets = 0;
//convert user team in a single score
double t1Score = TeamGenerator.getTeamScore(team1);
//opponent team strength
opponentScore = getOpponentScore(opponentName);
//win probability before simulation begins
double winProbability = t1Score / (t1Score + opponentScore);
//Output the win probability of the user's selected team
String output = "";
output += "Opponent: " + opponentName + "\n";
output += "\nWin Probability: " + String.format("%.2f", winProbability * 100) + "%\n";
output += "\nMATCH START! ";
int setNumber = 1;
//looping until 3 sets are won by one of the two teams
while (team1Sets < 3 && opponentSets < 3) {
//converting the team strengths into a probability
double baseChance = t1Score / (t1Score + opponentScore);
double finalChance = baseChance; //+ change;
//the random coin flip type simulate that is weighted by finalChance, this determines who will win the set
if (Math.random() < finalChance) {
team1Sets++;
} else {
opponentSets++;
}
//Outputting the sets that each team wins
output += "\nSet " + setNumber + ": User " + team1Sets + " - " + opponentSets + " " + opponentName;
setNumber++;
}
Reflection
From this project, I learned a lot about having many different parts separated in the program into classes makes each much clearer of what their purpose is and how we can specifically use them. I also got much more comfortable working with real data and making sure that it is clean and usable before running calculations on it. I am most proud of helping implement the scoring system for the teams and the simulation logic, since that is one of core parts of the project that make it really work. Debugging was also a large part of the experience for this project, and I learned it is important to check even the smallest pieces of code rather than trying to fix everything at once. Breaking down the code to find the issues was much easier. I grew as a teammate as well by talking out the issues of the code with each other and combining ideas to improve these issues and overall improve the project. When we had issues with different parts not connecting exactly right at the beginning, we were able to communicate and help test the issues together. Overall, I feel much more confident in my ability to builder larger programs, working with multiple classes, and implementing more advanced concepts such as optimization and simulation. At the beginning of this project, these topics felt very complicated, but now I feel confident I can understand how these really work in a real world problem.